package com.bootdo.system.util;

import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.codehaus.xfire.util.Base64;
import com.alibaba.fastjson.JSONObject;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Base64Util {
	
	private static final String key = "1234567890123456";
	public static void main(String[] args) {
		try {
			final String text = "字串文字";
			final byte[] textByte = text.getBytes("UTF-8");
			
		        String initVector = "0000000000000000"; // 16 bytes IV

		        String en = encrypt(key, initVector, "hello world, cryptopp");
		        System.out.println(en);
		        System.out.println(decrypt(key, initVector, en));
		        
		}catch(Exception e) {
			e.printStackTrace();
		}

	}
	
	
	 /**
     * 字符串转换成十六进制字符串
     */
    public static String str2HexStr(String str) {

        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
        }
        return sb.toString();
    }
    
    /**
    *
    * 十六进制转换字符串
    */

   public static byte[] hexStr2Bytes(String hexStr) {
       System.out.println("in len :" + hexStr.length());
       String str = "0123456789ABCDEF";
       char[] hexs = hexStr.toCharArray();
       byte[] bytes = new byte[hexStr.length() / 2];
       int n;
       for (int i = 0; i < bytes.length; i++) {
           n = str.indexOf(hexs[2 * i]) * 16;
           n += str.indexOf(hexs[2 * i + 1]);
           bytes[i] = (byte) (n & 0xff);
       }
       System.out.println("out len :" + bytes.length);
       System.out.println("ddd" + Arrays.toString(bytes));
       return bytes;
   }
   
   
   /**
    * bytes转换成十六进制字符串
    */
   public static String byte2HexStr(byte[] b) {
       String hs = "";
       String stmp = "";
       for (int n = 0; n < b.length; n++) {
           stmp = (Integer.toHexString(b[n] & 0XFF));
           if (stmp.length() == 1)
               hs = hs + "0" + stmp;
           else
               hs = hs + stmp;
       }
       return hs.toUpperCase();
   }

   
   public static String encrypt(String key, String initVector, String value) {
       try {
           System.out.println("key:\t" + Arrays.toString(key.getBytes("UTF-8")));
           System.out.println("iv:\t" + Arrays.toString(initVector.getBytes("UTF-8")));
           IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
           SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
           cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
           byte[] encrypted = cipher.doFinal(value.getBytes());
           System.out.println(Arrays.toString(encrypted));

           return byte2HexStr(encrypted);
       } catch (Exception ex) {
           ex.printStackTrace();
       }

       return null;
   }

   public static String decrypt(String key, String initVector, String encrypted) {
       try {
           IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
           SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
           cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
           byte[] original = cipher.doFinal(hexStr2Bytes(encrypted));

           return new String(original);
       } catch (Exception ex) {
           ex.printStackTrace();
       }

       return null;
   }

   
   /**
    * 解密用户敏感数据获取用户信息
    * @param sessionKey 数据进行加密签名的密钥
    * @param encryptedData 包括敏感数据在内的完整用户信息的加密数据
    * @param iv 加密算法的初始向量
    * @return
    */
   public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){
       // 被加密的数据
       byte[] dataByte = Base64.decode(encryptedData);
       // 加密秘钥
       byte[] keyByte = Base64.decode(sessionKey);
       // 偏移量
       byte[] ivByte = Base64.decode(iv);
       
       try {
              // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
           int base = 16;
           if (keyByte.length % base != 0) {
               int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
               byte[] temp = new byte[groups * base];
               Arrays.fill(temp, (byte) 0);
               System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
               keyByte = temp;
           }
           // 初始化
           Security.addProvider(new BouncyCastleProvider());
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
           SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
           AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
           parameters.init(new IvParameterSpec(ivByte));
           cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
           byte[] resultByte = cipher.doFinal(dataByte);
           if (null != resultByte && resultByte.length > 0) {
               String result = new String(resultByte, "UTF-8");
               return JSONObject.parseObject(result);
           }
       }  catch (Exception e) {
           e.printStackTrace();
       }
       return null;
   }
   
    

}
